﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;


namespace MedVis_MidiController
{
    public partial class frSetting : Form
    {
        public delegate void AddControllerToView(byte controlNumber, int controlValue);
        public AddControllerToView lastActiveDelegate;

        private List<ListItem> availbleControls = new List<ListItem>();
        private ListItem lastActive = null;
        private Button selected = null;
        private Point clickedOffset;
        public MidiDeviceSettings midiDeviceSettings { get; private set; }
        

        private void Button_MouseDown(object sender, MouseEventArgs e)
        {
            selected = (Button)sender;
            clickedOffset = e.Location;
        }

        private void Button_MouseMove(object sender, MouseEventArgs e)
        {
            if( selected != null && selected.GetType() == typeof(Button))
            {
                selected.Left += e.Location.X-clickedOffset.X;
                selected.Top += e.Location.Y-clickedOffset.Y;
            }
        }

        private void Button_MouseUp(object sender, MouseEventArgs e)
        {
            ListItem selectedItem = availbleControls.Find(
                delegate(ListItem mCS)
                {
                    return mCS.btn == selected;
                }
            );

            selectedItem.midiControllerSettings.loc = new Point(selected.Location.X, selected.Location.Y);

            selected = null;

            if (lastActive != null)
                lastActive.btn.BackColor = Color.Gray;

            lastActive = selectedItem;
            lastActive.btn.BringToFront();
            lastActive.btn.BackColor = Color.Aqua;

            updateVisibleSettings(selectedItem.midiControllerSettings);

        }

        private void updateVisibleSettings(MidiControllerSettings mCS)
        {
            comboBox_MidiControllerFunctions.SelectedItem = mCS.func;
            comboBox_MidiControllerFunctionParameterType.SelectedItem = mCS.functionParameterType;
            comboBox_MidiControllerType.SelectedItem = mCS.type;
            textbox_FunctionParameter.Text = mCS.functionParameter+"";
        }

        public frSetting(Form Owner)
        {
            InitializeComponent();
            lastActiveDelegate = new AddControllerToView(lastActiveController);

            comboBox_MidiControllerFunctions.DataSource = Enum.GetValues(typeof(MidiControllerFunctions));
            comboBox_MidiControllerFunctions.SelectionChangeCommitted += comboBox_MidiControllerFunctions_SelectionChangeCommitted;
            
            comboBox_MidiControllerFunctionParameterType.DataSource = Enum.GetValues(typeof(MidiControllerFunctionParameterType));
            comboBox_MidiControllerFunctionParameterType.SelectionChangeCommitted += comboBox_MidiControllerFunctionParameterType_SelectionChangeCommitted;

            comboBox_MidiControllerType.DataSource = Enum.GetValues(typeof(MidiControllerType));
            comboBox_MidiControllerType.SelectedIndexChanged += comboBox_MidiControllerType_SelectedIndexChanged;

            textbox_FunctionParameter.TextChanged += textbox_FunctionParameter_TextChanged;
            this.Owner = Owner;

            loadFromFile(((frmMain)Owner).MidiDeviceName+".xml");
        }

        void comboBox_MidiControllerType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lastActive == null)
                return;

            lastActive.midiControllerSettings.type = (MidiControllerType)comboBox_MidiControllerType.SelectedItem;
        }

        void textbox_FunctionParameter_TextChanged(object sender, EventArgs e)
        {
            if (lastActive == null)
                return;

            try
            {
                lastActive.midiControllerSettings.functionParameter = Int32.Parse(textbox_FunctionParameter.Text);
            }
            catch(Exception exc)
            {

            }
        }

        void comboBox_MidiControllerFunctionParameterType_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (lastActive == null)
                return;

            lastActive.midiControllerSettings.functionParameterType = (MidiControllerFunctionParameterType)comboBox_MidiControllerFunctionParameterType.SelectedItem;
        }

        void comboBox_MidiControllerFunctions_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (lastActive == null)
                return;

            lastActive.midiControllerSettings.func = (MidiControllerFunctions)comboBox_MidiControllerFunctions.SelectedItem;

        }
        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);


        }

        public void lastActiveController(byte controlNumber, int controlValue)
        {
            if (lastActive != null)
            {
                if (lastActive.midiControllerSettings.controlNumber == controlNumber)
                {
                    if (lastActive.midiControllerSettings.type == MidiControllerType.Knopf && controlValue != 0 && controlValue != 127)
                        comboBox_MidiControllerType.SelectedItem = MidiControllerType.Schieberegler;
                    return;
                }
                lastActive.btn.BackColor = Color.Gray;
            }

           var midiControllerSettings = midiDeviceSettings.addController(controlNumber);

           if (midiControllerSettings == null)
               return;


           ListItem selectedItem = availbleControls.Find(
               delegate(ListItem mCS)
               {
                   return mCS.midiControllerSettings == midiControllerSettings;
               }
           );


           if (selectedItem == null)
            {
                selectedItem = new ListItem(midiControllerSettings);
                var newControlbtn = new Button();
                    newControlbtn.Size = new Size(24,24);
                    newControlbtn.Visible = true;
                    newControlbtn.MouseDown += Button_MouseDown;
                    newControlbtn.MouseMove += Button_MouseMove;
                    newControlbtn.MouseUp += Button_MouseUp;
                    newControlbtn.BackColor = Color.Gray;

                selectedItem.btn = newControlbtn;
                availbleControls.Add(selectedItem);

                pictureBox1.Controls.Add(newControlbtn);
            }

            lastActive = selectedItem;
            lastActive.btn.BringToFront();
            lastActive.btn.BackColor = Color.Aqua;

            updateVisibleSettings(lastActive.midiControllerSettings);

            if (midiControllerSettings.type == MidiControllerType.Knopf && controlValue != 0 && controlValue != 127)
                comboBox_MidiControllerType.SelectedItem = MidiControllerType.Schieberegler;

        }

        private void ladenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Multiselect = false;
            if (openFileDialog1.ShowDialog() != DialogResult.OK)
                return;

            loadFromFile(openFileDialog1.FileName);
            
        }

        private void loadFromFile(string FileName)
        {
            try
            {
                midiDeviceSettings = MidiDeviceSettings.LoadFromFile(FileName);

                pictureBox1.Controls.Clear();
                if (midiDeviceSettings.backgroundImage != null)
                    pictureBox1.Image = (Image)midiDeviceSettings.backgroundImage;
                availbleControls = new List<ListItem>();

                midiDeviceSettings.midiControllerSettings.ForEach(delegate(MidiControllerSettings mCS)
                {
                    var newControl = new ListItem(mCS);
                    var newControlbtn = new Button();
                    newControlbtn.Location = mCS.loc;
                    newControl.btn = newControlbtn;
                    newControlbtn.Size = new Size(24, 24);
                    newControlbtn.Visible = true;
                    newControlbtn.MouseDown += Button_MouseDown;
                    newControlbtn.MouseMove += Button_MouseMove;
                    newControlbtn.MouseUp += Button_MouseUp;
                    newControlbtn.BackColor = Color.Gray;

                    availbleControls.Add(newControl);
                    pictureBox1.Controls.Add(newControlbtn);
                });

                
            }
            catch (Exception exc)
            {
                midiDeviceSettings = new MidiDeviceSettings();
                lastActive = null;
                selected = null;

                pictureBox1.Controls.Clear();
                availbleControls.Clear();
            }

        }

        private void beendenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void speichernToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.AddExtension = true;
            saveFileDialog1.DefaultExt = "xml";
            if (saveFileDialog1.ShowDialog() != DialogResult.OK)
                return;
            try
            {
                midiDeviceSettings.SaveToFile(saveFileDialog1.FileName);
            }
            catch(Exception exc)
            {}
        }

        private void frSetting_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.FormOwnerClosing)
            {
                try
                {
                    midiDeviceSettings.SaveToFile(((frmMain)Owner).MidiDeviceName + ".xml");
                }
                catch(Exception)
                {}
                return;
            }

            e.Cancel = true;
            this.Visible = false;

        }

        private void hintergrundBildToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Multiselect = false;
            if (openFileDialog1.ShowDialog() != DialogResult.OK)
                return;
            Bitmap bitmap = null; 
            try
            {
               bitmap  = new Bitmap(openFileDialog1.FileName);
            }
            catch(Exception exc)
            {}

            if (bitmap == null || midiDeviceSettings == null)
                return;

            midiDeviceSettings.backgroundImage = bitmap;
            pictureBox1.Image = (Image)bitmap;


        }

        private void controllerToolStripMenuItem_Click(object sender, EventArgs e)
        {
             lastActive = null;
             selected = null;

            midiDeviceSettings.clearController();
            pictureBox1.Controls.Clear();
            availbleControls.Clear();
        }

        private void btn_delete_Click(object sender, EventArgs e)
        {
            if (lastActive == null)
                return;

            pictureBox1.Controls.Remove(lastActive.btn);
            availbleControls.Remove(lastActive);


             lastActive = null;
             selected = null;
        }
    }
    public class ListItem
    {
        public Button btn { get; set; }
        public MidiControllerSettings midiControllerSettings { get; private set; }

        public ListItem(MidiControllerSettings midiControllerSettings)
        {
            this.midiControllerSettings = midiControllerSettings;
        } 
    }
}
